<template>
  <a-spin :loading="searchLoading" :tip="options.searchLoadingText" v-if="showSearch">
    <a-row>
      <a-col :flex="1">
        <a-form
          :model="searchForm"
          layout="inline"
          auto-label-width
          :label-align="options?.searchLabelAlign"
          ref="searchRef"
          @submit="handlerSearch"
        >
          <template v-for="(component, index) in searchColumns" :key="index">
            <a-form-item
              :field="component.dataIndex"
              :label="component.title"
              :label-col-style="{ width: component.searchLabelWidth ?? options.searchLabelWidth }"
            >
              <slot :name="`${component.dataIndex}`" v-bind="{ searchForm, component }">
                <component
                  :is="getComponentName(component.searchFormType ?? component.formType)"
                  :component="component"
                  :style="{ width: `${component.mWidth}px` }"
                />
              </slot>
            </a-form-item>
          </template>
          <a-form-item v-if="searchColumns.length > 0">
            <a-space>
              <slot name="searchBeforeButtons" />
              <slot name="searchButtons">
                <a-button type="primary" html-type="submit">
                  <template #icon>
                    <icon-search />
                  </template>
                  {{ options.searchSubmitButtonText }}
                </a-button>
                <a-button @click="resetSearch">
                  <template #icon>
                    <icon-refresh />
                  </template>
                  {{ options.searchResetButtonText }}
                </a-button>
              </slot>
              <slot name="searchAfterButtons" />
            </a-space>
          </a-form-item>
        </a-form>
      </a-col>
    </a-row>
  </a-spin>
</template>

<script setup>
import MaFormInput from "./searchFormItem/form-input.vue";
import MaFormPicker from "./searchFormItem/form-picker.vue";
import MaFormSelect from "./searchFormItem/form-select.vue";
import MaFormCascader from "./searchFormItem/form-cascader.vue";
import MaFormTreeSelect from "./searchFormItem/form-tree-select.vue";
import { cloneDeep, isFunction } from "lodash";

const options = inject("options");
const columns = inject("columns");

const searchLoading = ref(false);
const showSearch = ref(true);
const searchRef = ref(null);
const searchColumns = ref([]);

const searchForm = ref({});

provide("searchForm", searchForm);

const emit = defineEmits(["search"]);

const getSearchAllColumns = (cls = []) => {
  let sls = [];
  cls.map(item => {
    if (item.children && item.children.length > 0) {
      let tmp = getSearchAllColumns(item.children);
      sls.push(...tmp);
    } else if (item.dataIndex && item.search && item.search === true) {
      sls.push(item);
    }
  });
  return sls;
};

const initSearchColumns = () => {
  if (columns.value.length > 0) {
    searchColumns.value = cloneDeep(
      getSearchAllColumns(columns.value).filter(item => item.search === true && options.tabs?.dataIndex != item.dataIndex)
    );
  }
};

const handlerSearch = () => {
  emit("search", searchForm.value);
};

const resetSearch = async () => {
  searchRef.value?.resetFields();
  Object.keys(searchForm.value).map(item => {
    let temp = item.match(/^(.+)Min$/);
    if (temp) {
      searchForm.value[temp[1] + "Min"] = undefined;
      searchForm.value[temp[1] + "Max"] = undefined;
    }
  });
  if (options.resetSearch && isFunction(options.resetSearch)) {
    await options.resetSearch(searchForm.value);
  }
  emit("search", searchForm.value);
};

const componentList = ref({
  MaFormSelect: markRaw(MaFormSelect),
  MaFormPicker: markRaw(MaFormPicker),
  MaFormCascader: markRaw(MaFormCascader),
  MaFormTreeSelect: markRaw(MaFormTreeSelect),
  MaFormInput: markRaw(MaFormInput)
});

const getComponentName = formType => {
  if (["select", "radio", "checkbox", "transfer"].includes(formType)) {
    return componentList.value["MaFormSelect"];
  } else if (["date", "month", "year", "week", "quarter", "range", "time"].includes(formType)) {
    return componentList.value["MaFormPicker"];
  } else if (formType === "cascader") {
    return componentList.value["MaFormCascader"];
  } else if (formType === "tree-select") {
    return componentList.value["MaFormTreeSelect"];
  } else {
    return componentList.value["MaFormInput"];
  }
};

initSearchColumns();

const setSearchHidden = () => (showSearch.value = false);
const setSearchDisplay = () => (showSearch.value = true);
const setSearchLoading = () => (searchLoading.value = true);
const setSearchUnLoading = () => (searchLoading.value = false);
const getSearchFormRef = () => searchRef.value;
const getSearchColumns = () => searchColumns.value;

defineExpose({
  initSearchColumns,
  getSearchFormRef,
  getSearchColumns,
  showSearch,
  resetSearch,
  setSearchHidden,
  setSearchDisplay,
  setSearchLoading,
  setSearchUnLoading
});
</script>

<style scoped lang="less">
:deep(.arco-form-item-label-required-symbol svg) {
  vertical-align: baseline !important;
}
</style>
